/*
    tests/sh.cpp -- tests spherical harmonics evaluation code

    Enoki is a C++ template library that enables transparent vectorization
    of numerical kernels using SIMD instruction sets available on current
    processor architectures.

    Copyright (c) 2019 Wenzel Jakob <wenzel.jakob@epfl.ch>

    All rights reserved. Use of this source code is governed by a BSD-style
    license that can be found in the LICENSE file.
*/

#include "test.h"
#include <enoki/sh.h>

ENOKI_TEST(test00_sh) {
    using T = Array<float>;

    /* From mathematica */
    const float ref[100] = {
        0.2820947918f,   -0.2611690283f,    0.3917535424f,  -0.1305845141f,
        0.1560783472f,   -0.4682350417f,    0.2928635963f,  -0.2341175208f,
       -0.1170587604f,    0.02252796895f,   0.3310921732f,  -0.5409527810f,
        0.06411572364f,  -0.2704763905f,   -0.2483191299f,   0.1239038292f,
       -0.07663294720f,   0.05418767663f,   0.4730873479f,  -0.4301013494f,
       -0.1926808176f,   -0.2150506747f,   -0.3548155109f,   0.2980322214f,
       -0.02235127627f,   0.03401106316f,  -0.2037835426f,   0.08939333855f,
        0.5098360937f,   -0.1642890433f,   -0.3717265730f,  -0.08214452164f,
       -0.3823770702f,    0.4916633621f,   -0.05943686658f, -0.03669614710f,
        0.01095484717f,   0.09832164158f,  -0.3751138475f,   0.1148149412f,
        0.4035308753f,    0.1617920839f,   -0.4010373398f,   0.08089604195f,
       -0.3026481565f,    0.6314821768f,   -0.1094082055f,  -0.1060838764f,
        0.02912993451f,  -0.01914767451f,   0.03401803232f,  0.1978196393f,
       -0.5458487747f,    0.1174915463f,    0.1714596820f,   0.4252852218f,
       -0.2693765472f,    0.2126426109f,   -0.1285947615f,   0.6462035049f,
       -0.1592058926f,   -0.2134369792f,    0.09045704049f, -0.001997419283f,
        0.006375451838f, -0.06329912897f,   0.07377498039f,  0.3173673505f,
       -0.6530654560f,    0.09087000611f,  -0.1162228838f,   0.5245254059f,
       -0.02984068370f,   0.2622627030f,    0.08716716288f,  0.4997850336f,
       -0.1904774247f,   -0.3424226677f,    0.1961743797f,  -0.006603146547f,
       -0.009999592615f,  0.003740870431f,  0.02228152988f, -0.1464888644f,
        0.1282747834f,    0.4253232566f,   -0.6393164269f,   0.03874458847f,
       -0.3611982142f,    0.4202921001f,    0.2217097319f,   0.2101460500f,
        0.2708986607f,    0.2130952366f,   -0.1864672912f,  -0.4589014084f,
        0.3410943104f,   -0.01528121247f,  -0.03494751858f,  0.006246941013f
    };

    using Vector3f = Array<T, 3>;
    using Scalar = scalar_t<T>;

    Vector3f d = normalize(Vector3f(Scalar(1), Scalar(2), Scalar(3)));

    T out[100];
    for (size_t i = 0; i < 10; ++i) {
        sh_eval(d, i, out);
        for (size_t j = 0; j<(i+1)*(i+1); ++j) {
            assert(std::abs(out[j].coeff(0) - ref[j]) < 5e-6f);
        }
    }
}
